package com.misty.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.misty.admin.service.UsersService;
import com.misty.common.bean.Result;
import com.misty.common.constants.ResultEnum;
import com.misty.dao.domain.Role;
import com.misty.dao.domain.Users;
import com.misty.dao.dto.UsersDto;
import com.misty.dao.mapper.RoleMapper;
import com.misty.dao.mapper.UsersMapper;
import com.misty.dao.vo.UsersVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author cthulhu
 * @since 2022-11-21
 */
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements UsersService {

    @Resource
    private UsersMapper usersMapper;

    @Resource
    private RoleMapper roleMapper;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    /**
     *
     * @Param
     * @return
     * @Description 保存用户
     * @Date
     **/
    @Override
    public Result<?> saveUser(UsersDto user) {
        String encode = bCryptPasswordEncoder.encode(StrUtil.blankToDefault(user.getPassword(),"123456"));
        user.setPassword(encode);
        Users users = new Users();
        BeanUtil.copyProperties(user,users);
        users.setCreateTime(LocalDateTime.now());
        users.setUpdateTime(LocalDateTime.now());
        usersMapper.insert(users);

        QueryWrapper<Users> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username", user.getUsername());
        Integer userId = usersMapper.selectOne(userQueryWrapper).getId();

        for(String role :user.getRoles()){
            QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
            roleQueryWrapper.eq("name",role);
            Integer roleId = roleMapper.selectOne(roleQueryWrapper).getId();
            usersMapper.insertRoleIdWithUserId(userId,roleId);
        }
        return Result.success(ResultEnum.SUCCESS.getValue(),"保存用户成功!");
    }

    /**
     *
     * @Param
     * @return
     * @Description 更新用户
     * @Date
     **/
    @Override
    @Transactional(transactionManager = "mistyTransactionManager")
    public Result<?> updateUser(@RequestBody UsersDto user) {

        Users users = new Users();
        BeanUtil.copyProperties(user,users);
        users.setUpdateTime(LocalDateTime.now());

        Integer userId = user.getId();
        List<String> roleNames = usersMapper.selectRoleIdByUserId(userId);
        List<String> roles = user.getRoles();
        int size = roles.size();
        int roleNamesSize = roleNames.size();


        if (roles.containsAll(roleNames) && size == roleNamesSize ) {
            int update = usersMapper.updateById(users);
            if(update <= 0)return Result.error(ResultEnum.FAILURE.getValue(),"更新用户失败！");
            return Result.success(ResultEnum.SUCCESS.getValue(),"更新用户成功！");
        }else {
            roles.stream()
                    .filter( role->!roleNames.contains(role))
                    .forEach(role ->usersMapper.insertRoleIdWithUserId(userId,roleMapper.selectIdByRoleName(role)));
            roleNames.stream()
                    .filter(roleName -> !roles.contains(roleName))
                    .forEach(roleName ->usersMapper.deleteRoleIdWithUserId(userId,roleMapper.selectIdByRoleName(roleName)));
            int update = usersMapper.updateById(users);
            if(update <= 0)return Result.error(ResultEnum.FAILURE.getValue(),"更新用户失败！");
            return Result.success(ResultEnum.SUCCESS.getValue(),"更新用户成功！");
        }
    }


    /**
     *
     * @Param
     * @return
     * @Description 分页查询用户
     * @Date
     **/
    @Override
    public Result<?> Page(Integer pageNum, Integer pageSize, String search) {
        LambdaQueryWrapper<Users> userLambdaQueryWrapper = Wrappers.<Users>lambdaQuery();
        if (StrUtil.isNotBlank(search)) {
            userLambdaQueryWrapper.like(Users::getUsername, search);
        }
        Page<UsersDto> userPage = usersMapper.selectPageWithRole(new Page<>(pageNum, pageSize), userLambdaQueryWrapper);
        if(userPage.getTotal() <= 0){
            Result.error(ResultEnum.FAILURE.getValue(),"分页查询用户失败！");
        }
        return Result.success(ResultEnum.SUCCESS.getValue(),"分页查询用户成功！",userPage);
    }

    /**
     *
     * @Param
     * @return
     * @Description 根据用户ID获取用户
     * @Date
     **/
    @Override
    public Result<?> getById(Integer id) {
        Users user = usersMapper.selectById(id);
        if(ObjectUtil.isEmpty(user)){
            return Result.error("根据用户ID获取用户成功!");
        }
        UsersVo usersVo = new UsersVo();
        BeanUtil.copyProperties(user,usersVo);
        return Result.success("根据用户ID获取用户成功!",usersVo);
    }

    /**
     *
     * @Param
     * @return
     * @Description 删除用户以及对应角色
     * @Date
     **/
    @Override
    public Result<?> delete(Integer userId) {
        int deleteRUId = usersMapper.deleteRoleIdByUserId(userId);
        int deleteById = usersMapper.deleteById(userId);
        if(deleteById <= 0 && deleteRUId <= 0){
            return Result.error(ResultEnum.FAILURE.getValue(),"删除用户以及对应角色成功!");
        }
        return Result.success(ResultEnum.SUCCESS.getValue(),"删除用户以及对应角色成功!");
    }

}
